「 Istio 」快速开始

「 Istio 」快速开始


based on 1.15.0

简介

Istio 是一个开源服务网格,它透明地分层到现有的分布式应用程序上。 Istio 强大的特性提供了一种统一和更有效的方式来保护、连接和监视服务。 Istio 是实现负载平衡、服务到服务身份验证和监视的路径——只需要很少或不需要更改服务代码。它强大的控制平面带来了重要的特点,包括:

  • 使用 TLS 加密、强身份认证和授权的集群内服务到服务的安全通信
  • 自动负载均衡的 HTTP、gRPC、WebSocket,和 TCP 流量
  • 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制
  • 一个可插入的策略层和配置 API,支持访问控制、速率限制和配额
  • 对集群内的所有流量(包括集群入口和出口)进行自动度量、日志和跟踪

Istio 是为可扩展性而设计的,可以处理不同范围的部署需求。Istio 的控制平面运行在 Kubernetes 上,您可以将部署在该集群中的应用程序添加到您的网格中,将网格扩展到其他集群,甚至连接 VM 或运行在 Kubernetes 之外的其他端点。

安装

环境准备

Istio 与 Kubernetes 版本映射关系

参考:https://istio.io/latest/docs/setup/platform-setup/

Version Currently Supported Release Date End of Life Supported Kubernetes Versions Tested, but not supported
master No, development only
1.15 Yes August 31, 2022 ~March 2023 (Expected) 1.22, 1.23, 1.24, 1.25 1.16, 1.17, 1.18, 1.19, 1.20, 1.21
1.14 Yes May 24, 2022 ~January 2023 (Expected) 1.21, 1.22, 1.23, 1.24 1.16, 1.17, 1.18, 1.19, 1.20
1.13 Yes February 11, 2022 ~October 2022 (Expected) 1.20, 1.21, 1.22, 1.23 1.16, 1.17, 1.18, 1.19
1.12 Yes November 18, 2021 ~June 2022 (Expected) 1.19, 1.20, 1.21, 1.22 1.16, 1.17, 1.18
1.11 Yes August 12, 2021 ~Mar 2022 (Expected) 1.18, 1.19, 1.20, 1.21, 1.22 1.16, 1.17
1.10 No May 18, 2021 Jan 7, 2022 1.18, 1.19, 1.20, 1.21 1.16, 1.17, 1.22
1.9 No February 9, 2021 Oct 8, 2021 1.17, 1.18, 1.19, 1.20 1.15, 1.16
1.8 No November 10, 2020 May 12, 2021 1.16, 1.17, 1.18, 1.19 1.15
1.7 No August 21, 2020 Feb 25, 2021 1.16, 1.17, 1.18 1.15
1.6 and earlier No

profile 概念

参考:https://istio.io/latest/docs/setup/additional-setup/config-profiles/

1
2
3
4
5
6
7
8
9
$ istioctl profile list
Istio configuration profiles:
default
demo
empty
external
minimal
openshift
preview

profile 描述了 Istio 控制平面与数据平面的配置信息,以下为 Istio 内建的 profile 类别,同时也支持自定义的 profile。

  • default
    根据 IstioOperator API 的默认设置启动组件。 建议用于生产部署和 Multicluster Mesh 中的 Primary Cluster
  • demo
    这一配置具有适度的资源需求,旨在展示 Istio 功能的配置。它适合运行 Bookinfo 应用程序和相关任务
  • empty
    什么都不部署。可以作为自定义配置的基本配置文件
  • external
    用于配置远程集群由一个外部控制平面或者通过控制平面主要集群多集群网格
  • minimal
    与默认配置文件相同,但仅安装控制平面组件。这允许您使用单独的配置文件配置控制平面和数据平面组件(例如网关)
  • openshift
  • preview
    包含实验性功能。旨在探索 Istio 的新功能。不能保证稳定性、安全性和性能

不同的 profile 包含的核心组件

default demo minimal external empty preview
Core components
istio-egressgateway
istio-ingressgateway
istiod

展示 profile 具体内容

可以将 profile dump 出来,便于浏览和修改配置信息,可以看到 profile 的本质就是 IstioOperator 资源(详见下文)。

1
2
3
4
5
$ istioctl profile dump demo
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
...

也可以进一步通过 --config-path 参数(更多配置参考:https://istio.io/latest/docs/reference/config/),选择配置文件中指定路径的局部内容

1
2
3
4
5
6
7
8
9
10
$ istioctl profile dump --config-path components.pilot demo
enabled: true
k8s:
env:
- name: PILOT_TRACE_SAMPLING
value: "100"
resources:
requests:
cpu: 10m
memory: 100Mi

展示 profile 之间差别

可以看到 default 和 demo profile 之间的差别之一是,default 不会部署 istio-egressgateway 组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ istioctl profile diff default demo
spec:
components:
base:
enabled: true
cni:
enabled: false
egressGateways:
- - enabled: false
+ - enabled: true
+ k8s:
+ resources:
+ requests:
+ cpu: 10m
+ memory: 40Mi
name: istio-egressgateway

Istio 准备

Istio 可以通过 release 下载,也可以通过 Istio 官方提供的 downloadIstio 脚本下载,两者等价

1
2
3
4
$ curl -L https://istio.io/downloadIstio | sh -

# 脚本本身也提供了诸多参数,例如指定版本、指定架构下载
$ curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.15.0 TARGET_ARCH=x86_64 sh -

下载后包括以下内容,其中 istioctl 位于 bin 目录中,示例位于 samples 目录中

1
2
$ ls
bin LICENSE manifests manifest.yaml README.md samples tools

环境预检

1
2
3
$ istioctl x precheck
✔ No issues found when checking the cluster. Istio is safe to install or upgrade!
To get started, check out https://istio.io/latest/docs/setup/getting-started/

通过 Istioctl 安装

安装默认的 Istio(即 profile 为 default),该 profile 常用于生产环境。

1
$ istioctl install

也可以进行一些定制化(–set),例如:

1
$ istioctl install --set meshConfig.accessLogFile=/dev/stdout

该效果等价于(-f),使用 Istio Operator API 的方式更适用于生产环境。

1
2
3
4
5
6
7
$ istioctl install -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
accessLogFile: /dev/stdout
EOF

为了更好的演示 Istio 的特性,因此使用 demo 的 profile 安装 Istio。

1
2
3
4
5
6
$ istioctl install --set profile=demo -y
✔ Istio core installed
✔ Istiod installed
✔ Egress gateways installed
✔ Ingress gateways installed
✔ Installation complete

通过 Istio Operator 安装

类似于 Prometheus Operator,Istio 提供了通过 Operator 安装 Istio 的方式,只需要简单的更新 Istio Operator 声明的 API 对象,便可以非常便捷地处理多版本 Istio。

部署 Istio Operator

1
2
3
4
5
$ istioctl operator init
Installing operator controller in namespace: istio-operator using image: docker.io/istio/operator:1.15.0
Operator controller will watch namespaces: istio-system
✔ Istio operator installed
✔ Installation complete

在部署 Istio Operator 时,支持指定详细规格(更多配置参考:https://istio.io/latest/docs/reference/config/)。例如,在指定命名空间观测资源。

1
$ istioctl operator init --watchedNamespaces=istio-namespace1,istio-namespace2

部署 Istio Operator 后会产生以下资源

  • CRD

    1
    2
    $ kubectl get crd | grep istio
    istiooperators.install.istio.io 2022-05-14T03:11:20Z
  • Deployment

    1
    2
    3
    $ kubectl get deploy -n istio-operator
    NAME READY UP-TO-DATE AVAILABLE AGE
    istio-operator 1/1 1 1 6m20s
  • Service(用于暴露 Istio Operator 指标)

    1
    2
    3
    4
    5
    $ kubectl get svc -n istio-operator
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    istio-operator ClusterIP 10.96.212.28 <none> 8383/TCP 6m47s

    $ curl 10.96.212.28:8383/metrics
  • RBAC(细节不做展示)

创建 IstioOperator 资源

1
2
3
4
5
6
7
8
9
$ kubectl apply -f - <<EOF
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: example-istiocontrolplane
spec:
profile: demo
EOF

Istio Operator watch 到 IstioOperator 资源,然后根据 spec 中声明的详细规格(具体参考:更多配置参考:https://istio.io/latest/docs/reference/config/),安装部署 Istio 服务。

安装内容

安装 Istio(profile 为 demo)后会产生以下资源

  • Deployment

    1
    2
    3
    4
    5
    $ kubectl get deploy -n istio-system
    NAME READY UP-TO-DATE AVAILABLE AGE
    istio-egressgateway 1/1 1 1 4m14s
    istio-ingressgateway 1/1 1 1 4m14s
    istiod 1/1 1 1 4m23s
  • Service

    1
    2
    3
    4
    5
    $ kubectl get svc -n istio-system
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    istio-egressgateway ClusterIP 10.96.206.121 <none> 80/TCP,443/TCP 85s
    istio-ingressgateway LoadBalancer 10.96.159.246 <pending> 15021:31641/TCP,80:31235/TCP,443:30268/TCP,31400:32741/TCP,15443:31149/TCP 85s
    istiod ClusterIP 10.96.2.143 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 2m24s
  • CRD

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $ kubectl get crd | grep istio
    authorizationpolicies.security.istio.io 2022-09-13T05:55:57Z
    destinationrules.networking.istio.io 2022-09-13T05:55:57Z
    envoyfilters.networking.istio.io 2022-09-13T05:55:57Z
    gateways.networking.istio.io 2022-09-13T05:55:57Z
    istiooperators.install.istio.io 2022-09-13T05:55:57Z
    peerauthentications.security.istio.io 2022-09-13T05:55:57Z
    proxyconfigs.networking.istio.io 2022-09-13T05:55:57Z
    requestauthentications.security.istio.io 2022-09-13T05:55:58Z
    serviceentries.networking.istio.io 2022-09-13T05:55:58Z
    sidecars.networking.istio.io 2022-09-13T05:55:58Z
    telemetries.telemetry.istio.io 2022-09-13T05:55:58Z
    virtualservices.networking.istio.io 2022-09-13T05:55:58Z
    wasmplugins.extensions.istio.io 2022-09-13T05:55:58Z
    workloadentries.networking.istio.io 2022-09-13T05:55:58Z
    workloadgroups.networking.istio.io 2022-09-13T05:55:58Z
  • webhook

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ kubectl get mutatingwebhookconfigurations
    NAME WEBHOOKS AGE
    istio-revision-tag-default 4 8m57s
    istio-sidecar-injector 4 9m19s

    $ kubectl get validatingwebhookconfigurations
    NAME WEBHOOKS AGE
    istio-validator-istio-system 1 9m27s
    istiod-default-validator 1 9m4s
  • RBAC,PodDisruptionBudget,ConfigMap,EnvoyFilter(细节不做展示)

也可以查看 IstioOperator 对象来获取安装细节,installed-state 为 istioctl 安装的默认名称。

1
2
3
$ kubectl get istiooperator -n istio-system
NAME REVISION STATUS AGE
installed-state 10m

如果 Istio 集群由 Istio Operator 创建,那么 Istio Operator 会维护 IstioOperator 对象。

1
2
3
$ kubectl get istiooperator -n istio-system
NAMESPACE NAME REVISION STATUS AGE
istio-system example-istiocontrolplane HEALTHY 2m59s

此外,也可以生成安装的资源清单,并校验安装是否完整。

1
2
3
4
5
6
7
$ istioctl manifest generate --set profile=demo | istioctl verify-install -f -
...
✔ Service: istio-ingressgateway.istio-system checked successfully
✔ Service: istiod.istio-system checked successfully
Checked 15 custom resource definitions
Checked 3 Istio Deployments
✔ Istio is installed and verified successfully

配置校验

1
2
3
$ istioctl analyze --all-namespaces

✔ No validation issues found when analyzing all namespaces.

例如,当 VirtualService 指向的 Gateway 不存在时:

1
2
3
4
5
$ istioctl analyze --all-namespaces
Error [IST0101] (VirtualService default/bookinfo) Referenced gateway not found: "bookinfo-gateway-error"
Warning [IST0132] (VirtualService default/bookinfo) one or more host [*] defined in VirtualService default/bookinfo not found in Gateway default/bookinfo-gateway-error.
Error: Analyzers found issues when analyzing all namespaces.
See https://istio.io/v1.15/docs/reference/config/analysis for more information about causes and resolutions.

卸载

卸载 Istio Operator

1
2
3
4
5
6
7
8
$ istioctl operator remove
Removing Istio operator...
Removed Deployment:istio-operator:istio-operator.
Removed Service:istio-operator:istio-operator.
Removed ServiceAccount:istio-operator:istio-operator.
Removed ClusterRole::istio-operator.
Removed ClusterRoleBinding::istio-operator.
✔ Removal complete

卸载 Istio

--purge 会移除所有 Istio 资源,包括集群级别的(会对其他共享资源的 Istio 集群造成破坏),更多配置参考:https://istio.io/latest/docs/reference/config/

1
$ istioctl uninstall --purge

也可以通过安装的资源清单,执行卸载操作。

1
$ istioctl manifest generate --set profile=demo | kubectl delete -f -

默认情况下,istio-system namespace 不会被删除,需要手动删除。

1
$ kubectl delete ns istio-system

BookInfo 示例

这个示例部署了一个用于演示多种 Istio 特性的应用,该应用由四个单独的微服务构成。这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

BookInfo 应用分为四个单独的微服务

  • productpage 会调用 details 和 reviews 两个微服务,用来生成页面
  • details 包含了书籍的信息
  • reviews 包含了书籍相关的评论。它还会调用 ratings 微服务
  • ratings 包含了由书籍评价组成的评级信息

reviews 微服务有 3 个版本

  • v1 版本不会调用 ratings 服务
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息

该应用的端到端架构如下

BookInfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本。

所有的微服务都和 Envoy sidecar 集成在一起,被集成服务所有的出入流量都被 sidecar 所劫持,这样就为外部控制准备了所需的 Hook,然后就可以利用 Istio 控制平面为应用提供服务路由、遥测数据收集以及策略实施等功能。

根据名为 istio-ingressgateway 的 Service 的信息,可以明确 http 的访问地址为 http://178.104.162.69:31235

1
2
3
$ kubectl get svc -n istio-system istio-ingressgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.96.159.246 <pending> 15021:31641/TCP,80:31235/TCP,443:30268/TCP,31400:32741/TCP,15443:31149/TCP 3m34s

注入 Sidecar

Istio 默认自动注入 Sidecar,目前为 default 命名空间打上标签 istio-injection=enabled。

1
$ kubectl label namespace default istio-injection=enabled

部署测试应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created
service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created
service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created
service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created

状态检查,可以看到所有的 Pod 均为 2 容器,其中就包含了 Sidecar 容器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-79f774bdb9-m9njc 2/2 Running 2 20m
productpage-v1-6b746f74dc-8xps7 2/2 Running 2 20m
ratings-v1-b6994bb9-54w28 2/2 Running 2 20m
reviews-v1-545db77b95-57wkb 2/2 Running 2 20m
reviews-v2-7bf8c9648f-qj7zg 2/2 Running 2 20m
reviews-v3-84779c7bbc-fl2mx 2/2 Running 1 20m

$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.96.15.22 <none> 9080/TCP 13m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 43d
productpage ClusterIP 10.96.59.210 <none> 9080/TCP 13m
ratings ClusterIP 10.96.136.207 <none> 9080/TCP 13m
reviews ClusterIP 10.96.254.165 <none> 9080/TCP 13m

通过访问可以看到,Bookinfo 服务正在运行。

1
2
$ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>

创建 Gateway 与默认的 VirtualService

为了保证服务流量可以进入到服务网格,需要创建 Gateway 资源,同时创建一个默认的 VirtualService。

1
2
3
4
5
6
7
8
9
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

$ kubectl get gateway
NAME AGE
bookinfo-gateway 9s

$ kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 23m

创建的 Gateway,本质上是将入站流量交给满足标签 istio=ingressgateway 的 Pod 的流量接管。

也就是说流量从 istio-ingressgateway 的 Service 80 端口入站,转发到后端的 istio-ingressgateway 的 Pod。创建 Gateway 之后 istio-ingressgateway 会动态绑定 Gateway 中声明的 port 端口,因此需要保证流量可以从路由至该端口(即 istio-ingressgateway Service 的 Endpoint 端口中也同样为 80)

1
2
3
4
5
6
7
8
9
10
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP

创建的 VirtualService,绑定了上面创建的 Gateway,本质上是将匹配到的路由定向到 productpage Service 的 9080 端口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
spec:
gateways:
- bookinfo-gateway
hosts:
- '*'
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080

此时访问 http://178.104.162.69:31235/productpage,review 部分在 v1, v2, v3 版本平均切换

其实可以看到 VirtualService 将流量路由到 productpage 的 Service 后,此后的流量的路径还是 K8s 原生的路由方式

创建 DestinationRule

1
2
3
4
5
6
7
8
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

$ kubectl get destinationrule
NAME HOST AGE
details details 4m41s
productpage productpage 4m42s
ratings ratings 4m41s
reviews reviews 4m41s

此时 BookInfo 的 VirtualService 只是将流量转发到 productpage 上,而 productpage 只有 v1 版本,其他 DestinationRule 只是创建,未被引用,可以理解成 DestinationRule 注册了 productpage 的 v1 版本以及 reviews 的 v1,v2 和 v3 版本,如果后续需要使用,需要创建 VirtualService 路由流量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
spec:
host: productpage
subsets:
- name: v1
labels:
version: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3

由于没有 VirtualService 路由访问 Service 的流量,因此,此时访问页面,页面中 Review 微服务还是会三个版本平均切换的。

创建智能路由的 VirtualService

1
2
3
4
5
6
7
8
9
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

$ kubectl get virtualservice
NAME GATEWAYS HOSTS AGE
bookinfo ["bookinfo-gateway"] ["*"] 5d22h
details ["details"] 114s
productpage ["productpage"] 114s
ratings ["ratings"] 114s
reviews ["reviews"] 114s

创建的 VirtualService 的本质上是将访问各组件的所有的流量路由至对应的 v1 版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1

此时访问页面,页面中的 Review 只会有 v1 版本样式,即没有任何星星。

Author

Shen Xianghong

Posted on

2022-05-04

Updated on

2023-06-19

Licensed under